<?php

defined('IN_WORK') or exit('Authorization error');

/**
 * Cookie helper.
 *
 * @package    work
 * @category   lib
 * @author     fvzone
 * @copyright  (c) 2008-2011 fvzone.com
 * @license    http://www.opensource.org/licenses/bsd-license.php
 */
class cookie extends Work {

	/**
	 * @var string cookie 前缀key
	 */
	public static $salt = 'cookie_key';

	/**
	 * @var integer Cookie过期之前的秒数
	 */
	public static $expiration = 0;

	/**
	 * @var string cookie所存放的目录,默认为网站根目录
	 */
	public static $path = '/';

	/**
	 * @var string cookie所支持的域名, 默认为空
	 */
	public static $domain = NULL;

	/**
	 * @var boolean 仅通过安全连接传输的Cookie
	 */
	public static $secure = FALSE;

	/**
	 * @var  boolean  Only transmit cookies over HTTP, disabling Javascript access
	 */
	public static $httponly = FALSE;

	/**
	 * Gets the value of a signed cookie. Cookies without signatures will not
	 * be returned. If the cookie signature is present, but invalid, the cookie
	 * will be deleted.
	 *
	 *     //Get the "theme" cookie, or use "blue" if the cookie does not exist
	 *     $theme = cookie::get('theme', 'blue');
	 *
	 * @param   string  cookie name
	 * @param   mixed   default value to return
	 * @return  string
	 */
	public static function get($key, $default = NULL)
	{
		if (!isset($_COOKIE[$key]))
		{
			//The cookie does not exist
			return $default;
		}

		//Get the cookie value
		$cookie = $_COOKIE[$key];
		//Find the position of the split between salt and contents
		$split = strlen(cookie::salt($key, NULL));

		if (isset($cookie[$split]) AND $cookie[$split] === '~')
		{
			//Separate the salt and the value
			list ($hash, $value) = explode('~', $cookie, 2);
			if (cookie::salt($key, $value) === $hash)
			{
				//Cookie signature is valid
                //参数接受数组
				return unserialize(base64_decode($value));
			}

			//The cookie signature is invalid, delete it
			cookie::delete($key);
		}

		return $default;
	}

	/**
	 * Sets a signed cookie. Note that all cookie values must be strings and no
	 * automatic serialization will be performed!
	 *
	 *     //Set the "theme" cookie
	 *     cookie::set('theme', 'red');
	 *
	 * @param   string   name of cookie
	 * @param   string   value of cookie
	 * @param   integer  lifetime in seconds
	 * @return  boolean
	 * @uses    cookie::salt
	 */
	public static function set($name, $value, $expiration = NULL)
	{
		if ($expiration === NULL)
		{
			//Use the default expiration
			$expiration = cookie::$expiration;
		}

		if ($expiration !== 0)
		{
			//The expiration is expected to be a UNIX timestamp
			$expiration += time();
		}
        //序列化后用64位编码，方便数组传递
        $value = base64_encode(serialize($value));
		//Add the salt to the cookie value
		$value = cookie::salt($name, $value).'~'.$value;

		return setcookie($name, $value, $expiration, cookie::$path, cookie::$domain, cookie::$secure, cookie::$httponly);
	}

	/**
	 * Deletes a cookie by making the value NULL and expiring it.
	 *
	 *     cookie::delete('theme');
	 *
	 * @param   string   cookie name
	 * @return  boolean
	 * @uses    cookie::set
	 */
	public static function delete($name)
	{
		//Remove the cookie
		unset($_COOKIE[$name]);

		//Nullify the cookie and make it expire
		return setcookie($name, NULL, -86400, cookie::$path, cookie::$domain, cookie::$secure, cookie::$httponly);
	}

	/**
	 * Generates a salt string for a cookie based on the name and value.
	 *
	 *     $salt = cookie::salt('theme', 'red');
	 *
	 * @param   string   name of cookie
	 * @param   string   value of cookie
	 * @return  string
	 */
	public static function salt($name, $value)
	{
		//Determine the user agent
		$agent = isset($_SERVER['HTTP_USER_AGENT']) ? strtolower($_SERVER['HTTP_USER_AGENT']) : 'unknown';
		return sha1($agent.$name.$value.cookie::$salt);
	}

    /**
     * 判断cookie变量是否存在
     *
     * @access public
     * @param string $cookie_name    cookie的变量名
     * @return boolean
     */
    public static function is_set($cookie_name) {

        if (!$cookie_name) {
            return false;
        }

        return isset($_COOKIE[$cookie_name]);
    }

    /**
     * 清空cookie
     *
     * @access public
     * @return void
     */
    public static function clear()
    {
        unset($_COOKIE);
    }
}
